package main;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Vector;

public class Driver {
	
	/**
	 * main function
	 * @param args
	 */
	public static void main(String[] args) {
		ScienceStoreImpl store;
		ChiefScientist companyHead;
		System.out.println("RUNNING FROM DRIVER");
		store=createStore("EquipmentForSale.txt","ScientistsForPurchase.txt","LaboratoriesForSale.txt");
		companyHead=createCompany("InitialData.txt","ExperimentsList.txt",store);
		
		if(store!=null && companyHead!=null)
		{
			companyHead.startSimulation();
		}
	}

	
	/**
	 * creates a new company ChiefScientist - according to the information given in the parameters files 
	 * @param initialDataFilePath
	 * @param experimentFilePath
	 * @param store
	 * @return
	 */
	private static ChiefScientist createCompany(String initialDataFilePath, String experimentFilePath, ScienceStoreImpl store) {		

		ChiefScientist companyHead;
		BufferedReader initialDataFile,experimentFile;
		try{
		initialDataFile=new BufferedReader(new FileReader(initialDataFilePath));
		experimentFile=new BufferedReader(new FileReader(experimentFilePath));
		}catch(FileNotFoundException e)
		{
			Scanner scan=new Scanner(e.getMessage());
			System.out.println("file not found! file name: "+ scan.next());
			System.out.println("aborting Program");
			scan.close();
			return null;
		}
		
		Integer budget;
		Repository repository;
		Vector<HeadOfLaboratory> labHeads;
		
		Scanner scan=new Scanner(initialDataFile);
		String line;
		line=scan.nextLine();	//line="Budget"
		line=scan.nextLine();	
		budget=parseBudget(line);
		Statistics stats=new Statistics(budget);
		line=scan.nextLine();		//line="Repository"
		repository=new Repository();
		line=scan.nextLine();
		while(!line.equals("Laboratories"))
		{
			parsingEquipment(repository,new Scanner(line));
			line=scan.nextLine();
		}
		labHeads=new Vector<HeadOfLaboratory>();
		while(scan.hasNextLine())
		{
			line=scan.nextLine();
			parsingLaboratory(labHeads,new Scanner(line));
		}
		scan.close();
		
		//EXPERIMENTS
		ArrayList<Expirement> experimentsList=new ArrayList<Expirement>();
		scan=new Scanner(experimentFile);
		while(scan.hasNextLine())
		{
			line=scan.nextLine();
			parsingExperiment(experimentsList,new Scanner(line));
		}
		scan.close();
		
		companyHead=new ChiefScientist(labHeads, experimentsList, stats, store, repository);
		return companyHead;
	}

	/**
	 * parsing one experiment needed to be run at company
	 * @param experimentsList
	 * @param scan
	 */
	private static void parsingExperiment(ArrayList<Expirement> experimentsList, Scanner scan) {
		scan.useDelimiter("\t");
		//id
		Integer id=new Integer(scan.next());
		//reqExp
		Scanner scanReqExp=new Scanner(scan.next());
		Vector<Integer> reqExp=new Vector<Integer>();
		scanReqExp.useDelimiter(" ");
		while(scanReqExp.hasNext())
		{
			Integer exp=new Integer(scanReqExp.next());
			if(exp!=0)
			{
				reqExp.add(exp);
			}
		}
		scanReqExp.close();
		//specalization
		String spec=new String(scan.next());
		//reqItems
		Scanner scanReqEquipment=new Scanner(scan.next());
		scanReqEquipment.useDelimiter(" ");
		HashMap<String,Integer> reqEquipment=new HashMap<String,Integer>();
		while(scanReqEquipment.hasNext())
		{
			parsingEquipment(reqEquipment,new Scanner(scanReqEquipment.next()));
		}
		scanReqEquipment.close();
		//runtime in hours
		Integer runtime=new Integer(scan.next());
		//reward
		Integer reward=new Integer(scan.next());
		scan.close();
		Expirement exp=new Expirement(reward, reqExp, reqEquipment, runtime, spec, id);
		/*experimentsList.put(spec, exp);*/
		experimentsList.add(exp);		//order in experiments list is not important!
	}

	/**
	 * parsing one required equipment for a certain exp 
	 * @param labHeads
	 * @param scan
	 */
	private static void parsingEquipment(HashMap<String,Integer> reqEquipment, Scanner scan) {
		scan.useDelimiter(",");
		String name=scan.next();
		Integer amount=new Integer(scan.next());
		reqEquipment.put(name,amount);
		scan.close();
	}

/**
 * parsing one lab head initialy at company
 * @param labHeads
 * @param scan
 */
	private static void parsingLaboratory(Vector<HeadOfLaboratory> labHeads, Scanner scan) {
		scan.useDelimiter("\t");
		String headLabName=scan.next();
		String spec=scan.next();
		Integer numOfScientists=new Integer(scan.next());
		labHeads.add(new HeadOfLaboratory(headLabName, spec, numOfScientists.intValue()));
		scan.close();
		
	}

/**
 * parsing one equipment at initial repository
 * @param repository
 * @param scan
 */
	private static void parsingEquipment(Repository repository, Scanner scan) {
		scan.useDelimiter("\t");
		String name=scan.next();
		Integer amount=new Integer(scan.next());
		repository.addEquipment(name, amount.intValue());
		scan.close();
	}


	private static Integer parseBudget(String line) {
		return new Integer(line);
	}


	/**
	 * create a Science store from the files paths recieved as parameters
	 * @param filesNames
	 * @return
	 */
	private static ScienceStoreImpl createStore(String equipmentsFilePath, String scientistsFilePath, String laboratoriesFilePath) {
		ScienceStoreImpl store= new ScienceStoreImpl();
		BufferedReader equipmentsFile,scientistsFile,laboratoriesFile;
		try{
		equipmentsFile=new BufferedReader(new FileReader(equipmentsFilePath));
		scientistsFile=new BufferedReader(new FileReader(scientistsFilePath));
		laboratoriesFile=new BufferedReader(new FileReader(laboratoriesFilePath));
		}catch(FileNotFoundException e)
		{
			Scanner scan=new Scanner(e.getMessage());
			System.out.println("file not found! file name: "+ scan.next());
			System.out.println("aborting Program");
			scan.close();
			return null;
		}
		String line;
		Scanner scan=new Scanner(equipmentsFile);
		while(scan.hasNextLine())
		{
			line=scan.nextLine();
			parsingEquipment(store,new Scanner(line));
		}
		scan.close();
		scan=new Scanner(scientistsFile);
		while(scan.hasNextLine())
		{
			line=scan.nextLine();
			parsingScientist(store,new Scanner(line));
		}
		scan.close();
		scan=new Scanner(laboratoriesFile);
		while(scan.hasNextLine())
		{
			line=scan.nextLine();
			parsingLaboratory(store,new Scanner(line));
		}
		scan.close();
		return store;
	}

	/**
	 * parsing one lab initialy in store
	 * @param store
	 * @param scan
	 */
	private static void parsingLaboratory(ScienceStoreImpl store, Scanner scan) {
		scan.useDelimiter("\t");
		String headLabName=scan.next();
		String spec=scan.next();
		Integer numOfScientists=new Integer(scan.next());
		Integer price=new Integer(scan.next());
		store.addLabPack(headLabName, spec, price, numOfScientists);
		scan.close();
		
	}

	/**
	 * parsing one scientist initialy at store
	 * @param store
	 * @param scan
	 */
	private static void parsingScientist(ScienceStoreImpl store, Scanner scan) {
		scan.useDelimiter("\t");
		String name=scan.next();
		String spec=scan.next();
		Integer price=new Integer(scan.next());
		store.addScientistPack(spec, price, name);
		scan.close();
	}

	/**
	 * parsing one equipment pack initialy at store
	 * @param store
	 * @param scan
	 */
	private static void parsingEquipment(ScienceStoreImpl store, Scanner scan) {
		scan.useDelimiter("\t");
		String name=scan.next();
		Integer amount=new Integer(scan.next());
		Integer price=new Integer(scan.next());
		store.addEquipmentPack(name, price.intValue(), amount.intValue());
		scan.close();
	}

}
